#ifndef QTDBUSOBJECTMANAGER_H
#define QTDBUSOBJECTMANAGER_H

#include <qtdbusextrasglobal.h>

#include <QDBusConnection>
#include <QDBusObjectPath>
#include <QDBusVirtualObject>

class QtDBusObjectManagerPrivate;
class QTDBUSEXTRAS_EXPORT QtDBusObjectManager : protected QDBusVirtualObject
{
    Q_OBJECT
    Q_CLASSINFO("D-Bus Interface", "org.freedesktop.DBus.ObjectManager")
public:
    explicit QtDBusObjectManager(QObject *parent = nullptr);
    ~QtDBusObjectManager() override;

    QString introspect(const QString &path) const override;
    bool handleMessage(const QDBusMessage &message, const QDBusConnection &connection) override;

    QDBusConnection connection() const;
    QString path() const;
    QDBusConnection::VirtualObjectRegisterOption option() const;
    bool isRegistered() const;

    bool registerPath(const QDBusConnection &connection, const QString &path, QDBusConnection::VirtualObjectRegisterOption option = QDBusConnection::SubPath);
    void unregisterPath();

    bool registerObject(const QString &subPath, const QString &interface, QObject *object);
    void unregisterObject(const QString &subPath, const QString &interface);
    void unregisterObject(QObject *object);

    QObject *objectAt(const QString &path, const QString &interface) const;

public Q_SLOTS:
    QMap<QDBusObjectPath, QMap<QString, QVariantMap>> GetManagedObjects() const;

Q_SIGNALS:
    void InterfacesAdded(const QDBusObjectPath &path, const QMap<QString, QVariantMap> &interfaceInfos);
    void InterfacesRemoved(const QDBusObjectPath &path, const QStringList &interfaces);

protected:
    void catched(QObject *object, const QMetaMethod &signal, void **argv);
    void route(QObject *object, const QDBusMessage &message);

private:
    QScopedPointer<QtDBusObjectManagerPrivate> data;

    friend class QObject;
    friend class QtDBusProperties;
};

#endif // QTDBUSOBJECTMANAGER_H
